#include "TouchPanel.h"
#include "stm32f0xx_gpio.h"
#include "stm32f0xx_rcc.h"

// 引脚定义
#define Q165_PORT GPIOB
#define Q165_PIN GPIO_Pin_4

#define CP165_PORT GPIOB
#define CP165_PIN GPIO_Pin_3

#define PL165_PORT GPIOA
#define PL165_PIN GPIO_Pin_15

// 宏定义
#define INPUT_Q165() GPIO_ReadInputDataBit(Q165_PORT, Q165_PIN)
#define CP1_PIN_0() GPIO_ResetBits(CP165_PORT, CP165_PIN)
#define CP1_PIN_1() GPIO_SetBits(CP165_PORT, CP165_PIN)
#define PL1_PIN_0() GPIO_ResetBits(PL165_PORT, PL165_PIN)
#define PL1_PIN_1() GPIO_SetBits(PL165_PORT, PL165_PIN)

// 全局变量定义
volatile u8 key_status[6] = {0};     // 6个按键的状态
volatile u8 key_event[6] = {0};      // 6个按键的触发事件
volatile u8 key_long_event[6] = {0};  // 6个按键的长按事件
volatile u8 flush_status = 0;         // 状态刷新标志

// 从74HC165读取一个字节的数据
unsigned char read74HC165(void)
{
    unsigned char data = 0x00;
    int i;

    // 发送ST_CP的上升沿，以加载数据到输出寄存器
    CP1_PIN_1();
    data = 0x00;
    PL1_PIN_1();    // LOAD引脚置高
    delay_us(10);   // 短暂延时
    PL1_PIN_0();    // 拉低LOAD引脚
    delay_us(10);   // 短暂延时
    PL1_PIN_1();    // LOAD引脚置高
    delay_us(10);   // 短暂延时

    // 读取8位数据
    for (i = 0; i < 8; i++)
    {
        CP1_PIN_0();
        delay_us(5);  // 短暂延时
        data <<= 1;
        if (INPUT_Q165())
        {
            data |= 1;  // 设置相应的位
        }
        CP1_PIN_1();
        delay_us(5);  // 短暂延时
    }

    return data;
}

// 记录按键状态
void process_key_states(u8 keys_reg)
{
    static u16 button_press_counter[6] = {0};
    static u16 button_release_counter[6] = {0};

    const u8 noise_time = 2;    // 防抖时间
    const u16 long_time = 500;  // 5s

    // 调整按键位映射关系，从左到右编号0-5
    u8 mapped_keys = 0;
    mapped_keys |= ((keys_reg & 0x20) >> 5);  // 按键0 - 左起第一个按钮
    mapped_keys |= ((keys_reg & 0x10) >> 3);  // 按键1 - 左起第二个按钮
    mapped_keys |= ((keys_reg & 0x08) >> 1);  // 按键2 - 左起第三个按钮
    mapped_keys |= ((keys_reg & 0x04) << 1);  // 按键3 - 左起第四个按钮
    mapped_keys |= ((keys_reg & 0x02) << 3);  // 按键4 - 左起第五个按钮
    mapped_keys |= ((keys_reg & 0x01) << 5);  // 按键5 - 左起第六个按钮

    for (int i = 0; i < 6; i++)
    {
        if ((mapped_keys & (1 << i)) == 0)
        {
            button_press_counter[i]++;
            if (button_press_counter[i] == noise_time)
            {
                button_release_counter[i] = 0;
                key_status[i] = 1;
                key_event[i] = 1;  // 立即触发按键事件
            }
            if (button_press_counter[i] == long_time)
            {
                button_press_counter[i] = long_time + 1;
                key_long_event[i] = 1;
            }
            if (button_press_counter[i] >= long_time)
            {
                button_release_counter[i] = 0;
                button_press_counter[i] = long_time + 1;
                key_status[i] = 1;
            }
        }
        else
        {
            button_release_counter[i]++;
            if (button_release_counter[i] == noise_time)
            {
                button_press_counter[i] = 0;
                button_release_counter[i] = noise_time + 1;
                key_status[i] = 0;
            }
            if (button_release_counter[i] >= noise_time + 1)
            {
                button_press_counter[i] = 0;
                button_release_counter[i] = noise_time + 1;
                key_status[i] = 0;
            }
        }
    }

    if (flush_status != 0)
    {
        for (int i = 0; i < 6; i++)
        {
            key_long_event[i] = 0;  // 清除长按事件
        }
    }
}

// 扫描触摸面板并记录状态
void touch_panel_scan(void)
{
    static u8 scan_interval_counter = 0;
    u8 keys_reg;

    if (scan_interval_counter < 10)
    {
        scan_interval_counter++;
        return;
    }
    scan_interval_counter = 0;

    keys_reg = read74HC165();
    process_key_states(keys_reg);
}

// 获取按键事件（读取后自动清除）
uint8_t get_button_event(uint8_t button_index)
{
    if (button_index >= 6)
    {
        return 0;
    }
    
    uint8_t event = key_event[button_index];
    key_event[button_index] = 0;  // 清除事件
    return event;
}
